// Copyright (c) 2018, Bosch Software Innovations GmbH.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//    * Redistributions of source code must retain the above copyright
//      notice, this list of conditions and the following disclaimer.
//
//    * Redistributions in binary form must reproduce the above copyright
//      notice, this list of conditions and the following disclaimer in the
//      documentation and/or other materials provided with the distribution.
//
//    * Neither the name of the copyright holder nor the names of its
//      contributors may be used to endorse or promote products derived from
//      this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.


#ifndef RVIZ_DEFAULT_PLUGINS__TOOLS__TOOL_TEST_FIXTURE_HPP_
#define RVIZ_DEFAULT_PLUGINS__TOOLS__TOOL_TEST_FIXTURE_HPP_

#include <memory>

#include <QApplication>  // NOLINT cpplint cannot handle include order
#include <QKeyEvent>  // NOLINT cpplint cannot handle include order

#include "rviz_common/render_panel.hpp"
#include "rviz_common/viewport_mouse_event.hpp"

class ToolTestFixture
{
public:
  ToolTestFixture()
  : render_panel_(std::make_shared<rviz_common::RenderPanel>(nullptr))
  {}

  rviz_common::ViewportMouseEvent generateMouseMoveEvent(int x, int y)
  {
    return generateMouseEvent(x, y, QMouseEvent::MouseMove, Qt::NoButton, Qt::NoModifier);
  }

  rviz_common::ViewportMouseEvent generateMouseMoveWhileLeftClickedEvent(int x, int y)
  {
    return generateMouseEvent(x, y, QMouseEvent::MouseMove, Qt::LeftButton, Qt::NoModifier);
  }

  rviz_common::ViewportMouseEvent generateMouseLeftClick(int x, int y)
  {
    return generateMouseEvent(
      x, y, QMouseEvent::MouseButtonRelease, Qt::LeftButton, Qt::NoModifier);
  }

  rviz_common::ViewportMouseEvent generateMouseRightClick(int x, int y)
  {
    return generateMouseEvent(
      x, y, QMouseEvent::MouseButtonRelease, Qt::RightButton, Qt::NoModifier);
  }

  rviz_common::ViewportMouseEvent generateMousePressEvent(int x, int y)
  {
    return generateMouseEvent(x, y, QMouseEvent::MouseButtonPress, Qt::LeftButton, Qt::NoModifier);
  }

  rviz_common::ViewportMouseEvent generateMouseReleaseEvent(
    int x, int y, Qt::KeyboardModifiers modifiers = Qt::NoModifier)
  {
    return generateMouseEvent(x, y, QMouseEvent::MouseButtonRelease, Qt::LeftButton, modifiers);
  }

private:
  rviz_common::ViewportMouseEvent generateMouseEvent(
    int x, int y, QMouseEvent::Type type, Qt::MouseButton button, Qt::KeyboardModifiers modifiers)
  {
    auto mouseEvent = new QMouseEvent(type, QPointF(x, y), button, button, modifiers);
    return {render_panel_.get(), mouseEvent, x, y};
  }

  std::shared_ptr<rviz_common::RenderPanel> render_panel_;
};

#endif  // RVIZ_DEFAULT_PLUGINS__TOOLS__TOOL_TEST_FIXTURE_HPP_
